package com.own.business.level.business.service.impl;

import com.own.business.level.business.model.ExpModel;
import com.own.business.level.business.service.LevelConfigService;
import com.own.business.level.business.service.LevelUserHistoryService;
import com.own.business.level.business.service.LevelUserService;
import com.own.business.level.entity.bo.LevelUserBo;
import com.own.business.level.entity.map.LevelUserMapVo;
import com.own.business.level.entity.po.LevelUser;
import com.own.business.level.entity.query.LevelUserQuery;
import com.own.business.level.entity.vo.LevelUserVo;
import com.own.business.level.mapper.LevelUserMapper;
import com.own.component.common.base.service.impl.AbstractBaseService;
import com.own.component.common.hook.BaseUserDetailHook;
import com.own.component.common.login.user.BaseLoginUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * LevelUserServiceImpl
 *
 * @author chenxueli
 * @date 2022-07-25 10:44:00
 */
@Slf4j
@Service
public class LevelUserServiceImpl extends AbstractBaseService<
        LevelUser,
        LevelUserBo,
        LevelUserVo,
        LevelUserMapVo,
        LevelUserQuery,
        LevelUserMapper
        > implements LevelUserService, BaseUserDetailHook {

    @Resource
    private LevelUserMapper levelUserMapper;

    @Resource
    private LevelConfigService levelConfigService;
    @Resource
    private LevelUserHistoryService levelUserHistoryService;

    /**
     * 根据用户id添加用户的经验信息
     *
     * @param userId 用户id
     * @param model  经验模型
     * @return 是否添加成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean append(Long userId, ExpModel model) {
        var exp = model.getExp();
        if (exp <= 0) {
            return true;
        }
        var po = getPoById(LevelUser::getFkUserId, userId, () -> buildByUserId(userId));
        // 添加流水信息
        levelUserHistoryService.add(userId, po, model);
        // 主数据更新操作
        po.setExp(po.getExp() + exp);
        var updateModel = update(po);
        return updateModel.getFlag();
    }

    /**
     * 根据用户id创建用户等级信息
     *
     * @param userId 用户id
     * @return 用户等级信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public LevelUser buildByUserId(Long userId) {
        var addPo = new LevelUser().setFkUserId(userId).setExp(0);
        levelUserMapper.insert(addPo);
        return addPo;
    }

    /**
     * 根据id获取信息之后处理的信息
     *
     * @param vo vo对象
     * @return 处理的vo对象
     */
    @Override
    public LevelUserVo afterGetById(LevelUserVo vo) {
        // 获取规则信息
        var config1 = levelConfigService.next(vo.getExp());
        var config2 = levelConfigService.prev(vo.getExp());
        vo.setNextLevelExp(config1.getExp());
        vo.setNowExp(vo.getExp() - config2.getExp());
        vo.setLastLevelExp(config2.getExp());
        // 设置级别信息
        vo.setLevel(levelConfigService.level(vo.getExp()));
        return super.afterGetById(vo);
    }

    /**
     * 获取详情信息
     *
     * @param loginUser 登录的用户信息
     * @return 获取到的内容
     */
    @Override
    public Object detail(BaseLoginUser loginUser) {
        return getById(LevelUser::getFkUserId, loginUser.userId(), () -> buildByUserId(loginUser.userId()));
    }

    /**
     * 用户详情key
     *
     * @return key
     */
    @Override
    public String detailKey() {
        return "level";
    }
}
